home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 1996 March / Amiga-CD 1996 #3.iso / pd-software / mui_3.1 / developer / c / examples / class3.c < prev    next >
C/C++ Source or Header  |  1996-01-19  |  8KB  |  294 lines

  1. #include "demo.h"
  2.  
  3.  
  4. /***************************************************************************/
  5. /* Here is the beginning of our new class...                               */
  6. /***************************************************************************/
  7.  
  8. /*
  9. ** This is the instance data for our custom class.
  10. */
  11.  
  12. struct Data
  13. {
  14.     int x,y,sx,sy;
  15. };
  16.  
  17.  
  18. /*
  19. ** AskMinMax method will be called before the window is opened
  20. ** and before layout takes place. We need to tell MUI the
  21. ** minimum, maximum and default size of our object.
  22. */
  23.  
  24. SAVEDS ULONG mAskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg)
  25. {
  26.     /*
  27.     ** let our superclass first fill in what it thinks about sizes.
  28.     ** this will e.g. add the size of frame and inner spacing.
  29.     */
  30.  
  31.     DoSuperMethodA(cl,obj,msg);
  32.  
  33.     /*
  34.     ** now add the values specific to our object. note that we
  35.     ** indeed need to *add* these values, not just set them!
  36.     */
  37.  
  38.     msg->MinMaxInfo->MinWidth  += 100;
  39.     msg->MinMaxInfo->DefWidth  += 120;
  40.     msg->MinMaxInfo->MaxWidth  += 500;
  41.  
  42.     msg->MinMaxInfo->MinHeight += 40;
  43.     msg->MinMaxInfo->DefHeight += 90;
  44.     msg->MinMaxInfo->MaxHeight += 300;
  45.  
  46.     return(0);
  47. }
  48.  
  49.  
  50. /*
  51. ** Draw method is called whenever MUI feels we should render
  52. ** our object. This usually happens after layout is finished
  53. ** or when we need to refresh in a simplerefresh window.
  54. ** Note: You may only render within the rectangle
  55. **       _mleft(obj), _mtop(obj), _mwidth(obj), _mheight(obj).
  56. */
  57.  
  58. SAVEDS ULONG mDraw(struct IClass *cl,Object *obj,struct MUIP_Draw *msg)
  59. {
  60.     struct Data *data = INST_DATA(cl,obj);
  61.  
  62.     /*
  63.     ** let our superclass draw itself first, area class would
  64.     ** e.g. draw the frame and clear the whole region. What
  65.     ** it does exactly depends on msg->flags.
  66.     **
  67.     ** Note: You *must* call the super method prior to do
  68.     ** anything else, otherwise msg->flags will not be set
  69.     ** properly !!!
  70.     */
  71.  
  72.     DoSuperMethodA(cl,obj,msg);
  73.  
  74.     /*
  75.     ** if MADF_DRAWOBJECT isn't set, we shouldn't draw anything.
  76.     ** MUI just wanted to update the frame or something like that.
  77.     */
  78.  
  79.     if (msg->flags & MADF_DRAWUPDATE) /* called from our input method */
  80.     {
  81.         if (data->sx || data->sy)
  82.         {
  83.             SetBPen(_rp(obj),_dri(obj)->dri_Pens[SHINEPEN]);
  84.             ScrollRaster(_rp(obj),data->sx,data->sy,_mleft(obj),_mtop(obj),_mright(obj),_mbottom(obj));
  85.             SetBPen(_rp(obj),0);
  86.             data->sx = 0;
  87.             data->sy = 0;
  88.         }
  89.         else
  90.         {
  91.             SetAPen(_rp(obj),_dri(obj)->dri_Pens[SHADOWPEN]);
  92.             WritePixel(_rp(obj),data->x,data->y);
  93.         }
  94.     }
  95.     else if (msg->flags & MADF_DRAWOBJECT)
  96.     {
  97.         SetAPen(_rp(obj),_dri(obj)->dri_Pens[SHINEPEN]);
  98.         RectFill(_rp(obj),_mleft(obj),_mtop(obj),_mright(obj),_mbottom(obj));
  99.     }
  100.  
  101.     return(0);
  102. }
  103.  
  104.  
  105. SAVEDS ULONG mSetup(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  106. {
  107.     if (!(DoSuperMethodA(cl,obj,msg)))
  108.         return(FALSE);
  109.  
  110.     MUI_RequestIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  111.  
  112.     return(TRUE);
  113. }
  114.  
  115.  
  116. SAVEDS ULONG mCleanup(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  117. {
  118.     MUI_RejectIDCMP(obj,IDCMP_MOUSEBUTTONS|IDCMP_RAWKEY);
  119.     return(DoSuperMethodA(cl,obj,msg));
  120. }
  121.  
  122.  
  123. SAVEDS ULONG mHandleInput(struct IClass *cl,Object *obj,struct MUIP_HandleInput *msg)
  124. {
  125.     #define _between(a,x,b) ((x)>=(a) && (x)<=(b))
  126.     #define _isinobject(x,y) (_between(_mleft(obj),(x),_mright(obj)) && _between(_mtop(obj),(y),_mbottom(obj)))
  127.  
  128.     struct Data *data = INST_DATA(cl,obj);
  129.  
  130.     if (msg->muikey)
  131.     {
  132.         switch (msg->muikey)
  133.         {
  134.             case MUIKEY_LEFT : data->sx=-1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  135.             case MUIKEY_RIGHT: data->sx= 1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  136.             case MUIKEY_UP   : data->sy=-1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  137.             case MUIKEY_DOWN : data->sy= 1; MUI_Redraw(obj,MADF_DRAWUPDATE); break;
  138.         }
  139.     }
  140.  
  141.     if (msg->imsg)
  142.     {
  143.         switch (msg->imsg->Class)
  144.         {
  145.             case IDCMP_MOUSEBUTTONS:
  146.             {
  147.                 if (msg->imsg->Code==SELECTDOWN)
  148.                 {
  149.                     if (_isinobject(msg->imsg->MouseX,msg->imsg->MouseY))
  150.                     {
  151.                         data->x = msg->imsg->MouseX;
  152.                         data->y = msg->imsg->MouseY;
  153.                         MUI_Redraw(obj,MADF_DRAWUPDATE);
  154.                         MUI_RequestIDCMP(obj,IDCMP_MOUSEMOVE);
  155.                     }
  156.                 }
  157.                 else
  158.                     MUI_RejectIDCMP(obj,IDCMP_MOUSEMOVE);
  159.             }
  160.             break;
  161.  
  162.             case IDCMP_MOUSEMOVE:
  163.             {
  164.                 if (_isinobject(msg->imsg->MouseX,msg->imsg->MouseY))
  165.                 {
  166.                     data->x = msg->imsg->MouseX;
  167.                     data->y = msg->imsg->MouseY;
  168.                     MUI_Redraw(obj,MADF_DRAWUPDATE);
  169.                 }
  170.             }
  171.             break;
  172.         }
  173.     }
  174.  
  175.     return(DoSuperMethodA(cl,obj,msg));
  176. }
  177.  
  178.  
  179. /*
  180. ** Here comes the dispatcher for our custom class. 
  181. ** Unknown/unused methods are passed to the superclass immediately.
  182. */
  183.  
  184. SAVEDS ASM ULONG MyDispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  185. {
  186.     switch (msg->MethodID)
  187.     {
  188.         case MUIM_AskMinMax  : return(mAskMinMax  (cl,obj,(APTR)msg));
  189.         case MUIM_Draw       : return(mDraw       (cl,obj,(APTR)msg));
  190.         case MUIM_HandleInput: return(mHandleInput(cl,obj,(APTR)msg));
  191.         case MUIM_Setup      : return(mSetup      (cl,obj,(APTR)msg));
  192.         case MUIM_Cleanup    : return(mCleanup    (cl,obj,(APTR)msg));
  193.     }
  194.  
  195.     return(DoSuperMethodA(cl,obj,msg));
  196. }
  197.  
  198.  
  199.  
  200. /***************************************************************************/
  201. /* Thats all there is about it. Now lets see how things are used...        */
  202. /***************************************************************************/
  203.  
  204. int main(int argc,char *argv[])
  205. {
  206.     APTR app,window,MyObj;
  207.     struct MUI_CustomClass *mcc;
  208.  
  209.     init();
  210.  
  211.     /* Create the new custom class with a call to MUI_CreateCustomClass(). */
  212.     /* Caution: This function returns not a struct IClass, but a           */
  213.     /* struct MUI_CustomClass which contains a struct IClass to be         */
  214.     /* used with NewObject() calls.                                        */
  215.     /* Note well: MUI creates the dispatcher hook for you, you may         */
  216.     /* *not* use its h_Data field! If you need custom data, use the        */
  217.     /* cl_UserData of the IClass structure!                                */
  218.  
  219.     if (!(mcc = MUI_CreateCustomClass(NULL,MUIC_Area,NULL,sizeof(struct Data),MyDispatcher)))
  220.         fail(NULL,"Could not create custom class.");
  221.  
  222.     app = ApplicationObject,
  223.         MUIA_Application_Title      , "Class3",
  224.         MUIA_Application_Version    , "$VER: Class3 12.9 (21.11.95)",
  225.         MUIA_Application_Copyright  , "©1993, Stefan Stuntz",
  226.         MUIA_Application_Author     , "Stefan Stuntz",
  227.         MUIA_Application_Description, "Demonstrate the use of custom classes.",
  228.         MUIA_Application_Base       , "CLASS3",
  229.  
  230.         SubWindow, window = WindowObject,
  231.             MUIA_Window_Title, "A rather complex custom class",
  232.             MUIA_Window_ID   , MAKE_ID('C','L','S','3'),
  233.             WindowContents, VGroup,
  234.  
  235.                 Child, TextObject,
  236.                     TextFrame,
  237.                     MUIA_Background, MUII_TextBack,
  238.                     MUIA_Text_Contents, "\33cPaint with mouse,\nscroll with cursor keys.",
  239.                     End,
  240.  
  241.                 Child, MyObj = NewObject(mcc->mcc_Class,NULL,
  242.                     TextFrame,
  243.                     TAG_DONE),
  244.  
  245.                 End,
  246.  
  247.             End,
  248.         End;
  249.  
  250.     if (!app)
  251.         fail(app,"Failed to create Application.");
  252.  
  253.     set(window,MUIA_Window_DefaultObject, MyObj);
  254.  
  255.     DoMethod(window,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  256.         app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  257.  
  258.  
  259.  
  260. /*
  261. ** This is the ideal input loop for an object oriented MUI application.
  262. ** Everything is encapsulated in classes, no return ids need to be used,
  263. ** we just check if the program shall terminate.
  264. ** Note that MUIM_Application_NewInput expects sigs to contain the result
  265. ** from Wait() (or 0). This makes the input loop significantly faster.
  266. */
  267.  
  268.     set(window,MUIA_Window_Open,TRUE);
  269.  
  270.     {
  271.         ULONG sigs = 0;
  272.  
  273.         while (DoMethod(app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit)
  274.         {
  275.             if (sigs)
  276.             {
  277.                 sigs = Wait(sigs | SIGBREAKF_CTRL_C);
  278.                 if (sigs & SIGBREAKF_CTRL_C) break;
  279.             }
  280.         }
  281.     }
  282.  
  283.     set(window,MUIA_Window_Open,FALSE);
  284.  
  285.  
  286. /*
  287. ** Shut down...
  288. */
  289.  
  290.     MUI_DisposeObject(app);     /* dispose all objects. */
  291.     MUI_DeleteCustomClass(mcc); /* delete the custom class. */
  292.     fail(NULL,NULL);            /* exit, app is already disposed. */
  293. }
  294.